﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ElectromagneticCalculation
{
    public static class CurveFitting
    {
        /// <summary>
        /// 最小二乘法拟合多项式曲线
        /// </summary>
        /// <param name="x">x值</param>
        /// <param name="y">y值</param>
        /// <param name="degree">曲线最高次</param>
        /// <returns>洗漱</returns>
        public static double[] LeastSquares(double[] x, double[] y, int degree)
        {
            int n = x.Length;
            int m = degree + 1;

            double[,] A = new double[m, m];
            double[] B = new double[m];

            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < m; j++)
                {
                    for (int k = 0; k < n; k++)
                    {
                        A[i, j] += Math.Pow(x[k], i + j);
                    }
                }

                for (int k = 0; k < n; k++)
                {
                    B[i] += Math.Pow(x[k], i) * y[k];
                }
            }

            double[] result = GaussianElimination(A, B);
            return result;
        }

        // 高斯消元法求解线性方程组
        public static double[] GaussianElimination(double[,] A, double[] B)
        {
            int n = B.Length;
            double[] result = new double[n];

            for (int i = 0; i < n - 1; i++)
            {
                for (int j = i + 1; j < n; j++)
                {
                    double ratio = A[j, i] / A[i, i];

                    for (int k = i; k < n; k++)
                    {
                        A[j, k] -= ratio * A[i, k];
                    }

                    B[j] -= ratio * B[i];
                }
            }

            for (int i = n - 1; i >= 0; i--)
            {
                double sum = 0;

                for (int j = i + 1; j < n; j++)
                {
                    sum += A[i, j] * result[j];
                }

                result[i] = (B[i] - sum) / A[i, i];
            }

            return result;
        }
    }
}
